<!--created by yuyupeng-->
<!--2023/12/25-->
<!-- 实体查询条件表格 -->
<template>
  <div>
    <a-row>
      <a-col :span="12"> 实体查询条件 </a-col>
      <a-col :span="12">
        <a-row justify="end">
          <a-space style="margin-bottom: 7px">
            <Button.ButtonGroup size="small">
              <a-tooltip content="添加">
                <a-button @click="addField">
                  <template #icon>
                    <icon-plus />
                  </template>
                </a-button>
              </a-tooltip>
              <a-tooltip content="删除">
                <a-button
                  :disabled="selectedFields.length === 0"
                  @click="removeField"
                >
                  <template #icon>
                    <icon-minus />
                  </template>
                </a-button>
              </a-tooltip>
            </Button.ButtonGroup>
          </a-space>
        </a-row>
      </a-col>
    </a-row>

    <!--表格：表字段-->
    <a-table
      v-model:selected-keys="selectedFields"
      :columns="COLUMNS_FIELD"
      :data="fieldList"
      :scroll="{ x: 300, y: 300 }"
      row-key="id"
      :row-selection="rowSelection"
      :pagination="false"
    >
      <!--插槽：来源表格名称-下拉框-->
      <template #tableName="{ rowIndex }">
        <a-select
          v-model="fieldList[rowIndex].tableName"
          :disabled="fieldList[rowIndex].disabled"
          :options="tableNameOptions"
          @change="(val) => tableNameSelectChange(val, rowIndex)"
        />
      </template>
      <!--插槽：接口查询条件字段 表头-->
      <template #jsonNameTitle>
        <span style="color: red">* </span>接口查询条件字段
        <a-tooltip content="SearchParams里的传参字段，如userCode">
          <icon-question-circle />
        </a-tooltip>
      </template>
      <!--插槽：数据库表字段 表头-->
      <template #fieldNameTitle>
        <span style="color: red">* </span>数据库表字段
        <a-tooltip content="需要查询的数据库表字段，如user_code">
          <icon-question-circle />
        </a-tooltip>
      </template>
      <!--插槽：数据库表字段-下拉框-->
      <template #fieldName="{ rowIndex }">
        <a-select
          v-model="fieldList[rowIndex].fieldName"
          :disabled="fieldList[rowIndex].disabled"
          :options="columnKeySelectOptions(fieldList[rowIndex].tableName)"
        />
      </template>
      <!--插槽：可修改默认值 表头-->
      <template #mutableTitle>
        可修改默认值
        <a-tooltip
          content="只有配置了默认值时才生效，勾选后该字段将允许用户通过API的searchParams修改默认值"
        >
          <icon-question-circle />
        </a-tooltip>
      </template>
      <!--插槽（通用）：多选框-->
      <template #checkBox="{ rowIndex, column }">
        <a-checkbox
          v-model="fieldList[rowIndex][column.dataIndex]"
          :disabled="fieldList[rowIndex].disabled"
        />
      </template>

      <!--插槽（通用）：普通输入框-->
      <template #inputBox="{ rowIndex, column }">
        <a-input
          v-model="fieldList[rowIndex][column.dataIndex]"
          :disabled="fieldList[rowIndex].disabled"
        />
      </template>

      <!--插槽（通用）：数字输入框-->
      <template #numberBox="{ rowIndex, column }">
        <a-input-number
          v-model="fieldList[rowIndex][column.dataIndex]"
          :disabled="fieldList[rowIndex].disabled"
        />
      </template>

      <!--插槽：查询类型-->
      <template #selectType="{ rowIndex }">
        <a-select
          v-model="fieldList[rowIndex].selectType"
          :disabled="fieldList[rowIndex].disabled"
          :options="selectTypeOptions"
        />
      </template>
    </a-table>
  </div>
</template>

<script setup lang="ts">
  import { ref, reactive, computed, defineExpose, watch, toRefs } from 'vue';
  import {
    TableColumnData,
    TableRowSelection,
    Button,
  } from '@arco-design/web-vue';
  import { getDbTableColumns } from '@/api/infrastructure/business-entity';

  const props = defineProps({
    tableNameList: {
      // 数据库表名List
      type: Array,
      required: true,
    },
    dataSourceId: {
      // 数据源Id
      type: String,
      required: true,
    },
  });

  const { tableNameList, dataSourceId } = toRefs(props); // 根据props创建多个 ref 对象
  const tableColumnList = ref<any[]>([]); // 当前选择的实体关联的所有数据库表字段
  const rowSelection = reactive<TableRowSelection>({
    type: 'checkbox',
    showCheckedAll: true,
    onlyCurrent: false,
  });
  const selectTypeOptions = [
    { label: '=', value: 0 },
    { label: 'like', value: 1 },
    { label: '>', value: 2 },
    { label: '>', value: 3 },
    { label: '<=', value: 4 },
    { label: '>=', value: 5 },
  ];
  const selectedFields = ref<string[]>([]);
  const filterFlag = ref<boolean>(false);
  const searchValue = ref<string>('');
  const fieldList = computed(() => {
    // return [...editablefieldList.value, ...disabledfieldList.value];
    if (filterFlag.value) {
      // 要筛选一下
      const filterList = [] as any[];
      editablefieldList.value.forEach((item) => {
        if (
          item.defaultCondi.indexOf(searchValue.value) > -1 ||
          item.jsonName.indexOf(searchValue.value) > -1 ||
          item.tableName.indexOf(searchValue.value) > -1
        ) {
          filterList.push(item);
        }
      });
      return filterList;
    }
    return [...editablefieldList.value];
  });
  const tableNameOptions = computed(() => {
    // 来源表格名称下拉框数据源
    const options = [] as any[];
    tableNameList.value.forEach((item) => {
      options.push({
        label: item,
        value: item,
      });
    });
    return options;
  });
  // 可编辑的字段
  const editablefieldList = ref<any[]>([]);
  const COLUMNS_FIELD: TableColumnData[] = [
    {
      title: '序号',
      dataIndex: 'index',
      width: 60,
      fixed: 'left',
      render: ({ rowIndex }) => rowIndex + 1,
    },
    {
      title: '来源表格名称',
      dataIndex: 'tableName',
      slotName: 'tableName',
      width: 250,
    },
    {
      // title: '数据库表字段',
      titleSlotName: 'fieldNameTitle',
      dataIndex: 'fieldName',
      width: 150,
      slotName: 'fieldName',
    },
    {
      title: '查询类型',
      dataIndex: 'selectType',
      width: 150,
      slotName: 'selectType',
    },
    {
      // title: '接口查询条件字段',
      titleSlotName: 'jsonNameTitle',
      dataIndex: 'jsonName',
      width: 200,
      slotName: 'inputBox',
    },
    {
      title: '默认值',
      dataIndex: 'defaultCondi',
      width: 150,
      slotName: 'inputBox',
    },
    {
      // title: '可修改默认值',
      titleSlotName: 'mutableTitle',
      dataIndex: 'mutable',
      width: 200,
      slotName: 'checkBox',
    },
    /* {
      title: '备注',
      dataIndex: 'comment',
      slotName: 'inputBox',
      width: 150,
    },
     {
      title: '小数点',
      dataIndex: 'decimalPoint',
      slotName: 'numberBox',
      width: 150,
    },
    {
      title: '是否主键',
      dataIndex: 'primaryKey',
      width: 100,
      align: 'center',
      slotName: 'checkBox',
    }, */
  ];
  watch(searchValue, (val) => {
    if (val.length > 0) {
      filterFlag.value = true;
    } else {
      filterFlag.value = false;
    }
  });
  const addField = () => {
    const newRow = {
      id: new Date().getTime(),
      jsonName: '',
      selectType: 0,
      fieldName: '',
      defaultCondi: '',
      tableName: tableNameList.value[0],
      mutable: false,
    };
    editablefieldList.value = [...editablefieldList.value, newRow];
  };
  const removeField = () => {
    const newList = editablefieldList.value.filter(
      (elem) => !selectedFields.value.includes(elem.id)
    );
    editablefieldList.value = newList;
    selectedFields.value = [];
  };
  const getFieldList = () => {
    return fieldList.value;
  };
  const clearFieldList = () => {
    editablefieldList.value = [];
  };
  /**
   * 批量添加表格信息，库表映射的时候可以用到
   * @param tbData
   */
  const addTbDataBatch = (tbData: any[]) => {
    editablefieldList.value = editablefieldList.value.concat(tbData);
  };
  /**
   * @description 来源表格名称下拉框变化触发
   * @param tableName
   * @param index
   */
  const tableNameSelectChange = (tableName: string, index: number) => {
    editablefieldList.value.forEach((item) => {
      if (item.id === fieldList.value[index].id) {
        // 表名称变化后要重置一下这一行的数据
        item.jsonName = '';
        item.selectType = 0;
        item.fieldName = '';
        item.defaultCondi = '';
        item.mutable = false;
      }
    });
  };
  /**
   * @description 获取表格字段下拉框数据源
   */
  const getColumnKeySelectOptions = () => {
    tableColumnList.value = [];
    tableNameList?.value.forEach(async (item) => {
      const { data } = await getDbTableColumns(dataSourceId.value, item);
      data.forEach((e: any) => {
        e.tableName = item;
        tableColumnList.value.push(e);
      });
    });
  };
  /**
   * @description 根据表名生成对应的表字段下拉框数据源
   * @param tableName
   */
  const columnKeySelectOptions = (tableName: string) => {
    const selectOptions = [] as any[];
    tableColumnList.value.forEach((item: any) => {
      if (item.tableName === tableName) {
        selectOptions.push({
          label: item.name,
          value: item.name,
        });
      }
    });
    return selectOptions;
  };
  /**
   * @description 初始化
   */
  const init = () => {
    clearFieldList();
    getColumnKeySelectOptions();
  };
  defineExpose({ init, getFieldList, clearFieldList, addTbDataBatch }); // 在<srcipt setup>的写法中，想要子组件中的方法可以被父组件调用，要通过defineExpose将方法暴露出去
</script>
